package hxgo

import (
	"strconv"
	"os"
	"encoding/json"
	"log"
)

// constants for supported format
const (
	CONFIG_JSON = 1
)

// Config object
type Config struct {
	Data map[string]string
	Type int
	File string
}

// Config loader interface, read file and return map[string]string as key/value pair value
type ConfigLoader interface {
	Load(configFile string) map[string]string
}

// get string data by key string
func (this *Config) String(key string) string {
	if this.Data[key] == "" {
		return ""
	}
	return this.Data[key]
}

// get string data, if no data use default value
func (this *Config) StringOr(key string, def string) string {
	value := this.String(key)
	if value == "" {
		value = def
	}
	return value
}

// get int data by key string
func (this *Config) Int(key string) int {
	if this.Data[key] == "" {
		return 0
	}
	i, _ := strconv.Atoi(this.Data[key])
	return i
}

// get int data, if no data use default int value
func (this *Config) IntOr(key string, def int) int {
	value := this.Int(key)
	if value == 0 {
		value = def
	}
	return value
}

// get float data by key string
func (this *Config) Float(key string) float64 {
	if this.Data[key] == "" {
		return 0.0
	}
	f, _ := strconv.ParseFloat(this.Data[key], 10)
	return f
}

// get float data, if no data use default float value
func (this *Config) FloatOr(key string, def float64) float64 {
	value := this.Float(key)
	if value == 0.0 {
		value = def
	}
	return value
}

// get bool data by key string
func (this *Config) Bool(key string) bool {
	if this.Data[key] == "" {
		return false
	}
	b, _ := strconv.ParseBool(this.Data[key])
	return b
}

// set string data by key string, only support string
func (this *Config) Set(key string, value string) {
	this.Data[key] = value
}

//----------------------------------------------------------

// Config Loader for json file
type ConfigJsonLoader struct {

}

// implement Load method
func (this *ConfigJsonLoader) Load(configFile string) map[string]string {
	f, e := os.Open(configFile)
	if e != nil {
		log.Fatal(e)
	}
	defer f.Close()
	decoder := json.NewDecoder(f)
	data := map[string]string{}
	e2 := decoder.Decode(&data)
	if e2 != nil {
		log.Fatal(e2)
	}
	return data
}

//----------------------------------------------------------

// create new config with file and type settings
func NewConfig(configFile string, configType int) *Config {
	config := &Config{}
	if configType == CONFIG_JSON {
		loader := ConfigJsonLoader{}
		config.Data = loader.Load(configFile)
		config.Type = CONFIG_JSON
		config.File = configFile
		return config
	}
	return config
}


